/*
    1. 链式调用中，只有前一个 then 的回调执行完毕后，跟着的 then 中的回调才会被加入至微任务队列
    2. 每个链式调用的开端会首先依次进入微任务队列
    3. 同一个 Promise 的每个链式调用的开端会首先依次进入微任务队列
*/

setTimeout(() => console.log('a'));   // 宏1

Promise.resolve().then(    // 微1
    () => console.log('b')
).then(   // 微2
    () => Promise.resolve('c').then((data) => {  // 微3
        setTimeout(() => console.log('d')); // 宏2
        console.log('f');
        return data;
    })
).then(data => console.log(data));   // 微4


/*
    - Step1: 执行script
        1. 把 setTimeout加入宏任务队列（宏1）
        2. 执行Promise.resolve()，更改状态为resolved，没有值，把then加入微任务队列（微1）
        3. 前面的then回调还没执行所以后面的then先不加入微任务队列
        目前状态：
        宏任务队列 [宏1]
        微任务队列 [微1]

    - Step2: 执行微任务队列   [微1]
        1. 执行微1———————————————————————— b
        2. 把then加入微任务队列（微2）   [微2]
        3. 后面的then因为微2 没有执行回调，所以暂不加入 
        4. 微任务队列没有清空，所以继续执行微2， Promise.resolve()，更改状态为resolved，保存值'c'，
            把then（微3）加入微任务队列   [微3]
        5. 执行微3，把setTimeout（宏2）加入宏任务队列，打印————————————————f，返回data，即保存的值'c'
        6. 此时微2执行完毕，把下面的then（微4）加入微任务队列 [微4]
        7. 执行微4， 打印——————————————————————————c
        目前状态：
        宏任务队列 [宏1 宏2]
        微任务队列 []

        /
            如果在执行微任务的过程中，产生了新的微任务，同样会将该微任务添加到微任务队列中，
            V8 引擎一直循环执行微任务队列中的任务，直到队列为空才算执行结束。
            也就是说在执行微任务过程中产生的新的微任务并不会推迟到下个宏任务中执行，而是在当前的宏任务中继续执行

        /

    - Step3： 执行宏任务队列  [宏1 宏2]
        1. 执行宏1，打印————————————————————————a
        2. 执行宏2，打印————————————————————————d
        目前状态：
        宏任务队列 []
        微任务队列 []

        执行完毕，最终打印结果： b f c a d
*/

/*
    1. 微任务和宏任务是绑定的，每个宏任务在执行时，会创建自己的微任务队列
    2. 微任务的执行时长会影响到当前宏任务的时长
    3. 在一个宏任务中，分别创建一个用于回调的宏任务和微任务，无论什么情况下，微任务都早于宏任务执行
*/


